unit gmFilterBridges;

interface
//uses Classes, Controls;
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, ComCtrls;


type
  TValueType = (varInteger, varBoolean);

  TgmFilterBridge = class;//far definition
  
  TgmFilterParam = class(TObject)
  private
    FControls: TList;
    FCurrentValue: Variant;
    FDefaultValue: Variant;
    FUpdateCount : Integer;
    FUpdatingControls : Boolean;
    FFilterBridge : TgmFilterBridge;
    FValueType: TValueType;
    FIsStored: boolean;
    procedure SetCurrentValue(const Value: Variant);
    function GetCurrentValue: Variant;
  protected
    procedure BeginUpdate; //virtual;
    procedure EndUpdate; //virtual;
  public
    constructor Create(AFilterBridge : TgmFilterBridge);
    destructor Destroy; override;

    procedure OnChange(Sender: TObject);

    property Controls: TList read FControls;
    property CurrentValue : Variant read GetCurrentValue write SetCurrentValue;
    property ValueType : TValueType read FValueType write FValueType; //used for export to string
    property DefaultValue : Variant read FDefaultValue write FDefaultValue;
    property IsStored : boolean read FIsStored write FIsStored; //for radiobox, we cant make sure what is the currentvalue.
  end;

  //----------------------------------------------------------------------------
  TgmFilterBridge = class(TStringList)
  private
    FOnChange: TNotifyEvent;
  protected
    procedure DoChange;
  public
    function Add(Section : string; AObject : TControl; AValueType: TValueType = varInteger): TgmFilterParam; reintroduce; overload;
    function Add(const S: string): Integer; overload; override;
    function AsString : string;
    property OnChange: TNotifyEvent read FOnChange write FOnchange;
  end;

  TgmParamArray = class(TStringList)
  private
    function GetParams(index: string): Variant;
  public
    property Params[index : string] : Variant read GetParams; default;
    function AsBoolan(index: string): Boolean;
    function AsInteger(index: string) : Integer;
  end;

  function ParamArray(AParamsStr : string): TgmParamArray;

implementation
uses GR32_Containers;


function ParamArray(AParamsStr : string): TgmParamArray;
var i : Integer;
  s,s1,s2 : string;
  v : Variant;
  tmp : TStrings;
begin
  Result := TgmParamArray.Create;
  Result.CommaText := AParamsStr;
  {tmp := TStringList.Create;
  tmp.Text := Trim( StringReplace( AParamsStr, ',' , #13#10,  [rfReplaceAll] ) );


  Result := TgmParamArray.Create;
  for i := 0 to tmp.Count-1  do
  begin
    s  := tmp[i];
    s1 := Trim( Copy( s, 1,             Pos('=', s) -1) );
    s2  := Trim( Copy( s, Pos('=',s) +1, Length(s) ) );
    Result.AddObject(s,TObject(s1) );
  end;

  tmp.Free;}
end;  

{ TgmFilterBridge }

function TgmFilterBridge.Add(const S: string): Integer;
begin
  Result := inherited Add(S);
end;

function TgmFilterBridge.Add(Section: string; AObject: TControl;  AValueType: TValueType): TgmFilterParam;
var
  //ca : TControlsArray;
  //cl : TList; //List of Controls
  i : Integer;
  //Result : TgmFilterParam;
begin
  //Result := Count;
  {if not Sorted then
    Result := FCount
  else}
    //if Find(Trim(Section), i) then
    i := IndexOf(Section);
    if i >= 0 then
    begin
      {case Duplicates of
        dupIgnore: Exit;
        dupError: Error(@SDuplicateString, 0);
      end;}

      {ca := TControlsArray( self.Objects[result] );
      SetLength(ca, Length(ca) +1);
      ca[Length(ca) - 1] := AObject;
      Objects[result] := TObject(ca) ;}

      {cl := Objects[result] as TList;
      cl.Add(AObject);
      Objects[Result] := cl;}

      //TList(Objects[Result]).Add(AObject);
      Result := TgmFilterParam(Objects[i]);
      Result.Controls.Add(AObject);
      Result.ValueType := AValueType;
    end
    else
    begin
      //SetLength(ca,1);
      //ca[0] := AObject;
      //InsertItem(Result, Section, TObject(ca) );

      {cl := TList.Create;
      cl.Add(AObject);
      //InsertItem(Result, Section, cl );
      AddObject(Section,cl);}
      Result := TgmFilterParam.Create(Self);
      Result.Controls.Add(AObject);
      Result.ValueType := AValueType;
      AddObject(Section, Result);
    end;
end;

function TgmFilterBridge.AsString: string;
var i : Integer;
  s : string;
  param : TgmFilterParam;
begin
  Result := '';
  for i := 0 to Count-1 do
  begin
    if i > 0 then
      Result := Result + ', ';

    param := TgmFilterParam(Self.Objects[i]);

    case param.ValueType of
      varInteger : s := IntToStr(param.CurrentValue);
      varBoolean : s := BoolToStr(param.CurrentValue, True);
    end;

    Result := Result + Format('%s=%s',[Self.Strings[i], s]);
  end;

end;

procedure TgmFilterBridge.DoChange;
begin
  if Assigned( FOnChange) then
    FOnChange(Self);
end;

{ TgmFilterParam }

procedure TgmFilterParam.BeginUpdate;
begin
  Inc(FUpdateCount);
end;

constructor TgmFilterParam.Create(AFilterBridge : TgmFilterBridge);
begin
  inherited Create;
  FFilterBridge := AFilterBridge;
  FControls := TList.Create;
  FUpdatingControls := False;
  FIsStored := True;
end;

destructor TgmFilterParam.Destroy;
begin
  FControls.Free;
  inherited;
end;

procedure TgmFilterParam.EndUpdate;
begin
  Dec(FUpdateCount);
end;

function TgmFilterParam.GetCurrentValue: Variant;
begin
  Result := FCurrentValue;
  if not FIsStored then
  begin
    if TControl(Controls[0]) is TRadioButton then
      Result := TRadioButton(Controls[0]).Checked;
  end;
end;

procedure TgmFilterParam.OnChange(Sender: TObject);
begin
  if FUpdatingControls then Exit;

  FUpdatingControls := True;

  if sender is TEdit then
    CurrentValue := TEdit(Sender).text
  else
  if sender is TTrackBar then
    CurrentValue := TTrackBar(Sender).Position
  else
  if sender is TRadioButton then
    CurrentValue := TRadioButton(Sender).Checked
  else
  if sender is TCheckBox then
    CurrentValue := TCheckBox(Sender).Checked
  ;

  FFilterBridge.DoChange;//send to root

  FUpdatingControls := False;
end;

procedure TgmFilterParam.SetCurrentValue(const Value: Variant);
var i : Integer;
  C : TControl;
begin
  FCurrentValue := Value;
  for i := 0 to Controls.Count -1  do
  begin
    c := TControl(Controls[i]);
    if C is TEdit then
      TEdit(C).Text := Value
    else
    if C is TTrackBar then
      TTrackBar(C).Position := Value
    else
    if C is TRadioButton then
      TRadioButton(C).Checked := Value
    else
    if C is TCheckBox then
      TCheckBox(C).Checked := Value
    else
    if C is TLabel then
      TLabel(C).Caption := Value
    ;
  end;

end;

{ TgmParamArray }

function TgmParamArray.AsBoolan(index: string): Boolean;
begin
  Result := getparams(index);
end;

function TgmParamArray.AsInteger(index: string): Integer;
begin
  Result := GetParams(index);
end;

function TgmParamArray.GetParams(index: string): Variant;
var i : Integer;
begin
//  i := self.IndexOfName(index);
  try
    Result := self.Values[index];
  except
    Result := '0';
  end;

  {Result := '';
  i := IndexOf(index);
  if i >= 0 then
  begin
//    Result := Objects[i];
  end;
  }
end;

end.
